﻿using DevComponents.DotNetBar;
using DevComponents.DotNetBar.Metro;
using DevComponents.DotNetBar.SuperGrid;
using Kimd.Common;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WorkStation.Common;
using WorkStation.UI.Controls;

namespace WorkStation.UI
{
    public partial class FormModule : Form, IUserChange
    {
        private FormMain _mainForm;
        private FormXYZR _axisForm;
        public FormModule(FormMain mainForm)
        {
            InitializeComponent();
            this._mainForm = mainForm;
        }

        private void btn_Save_Click(object sender, EventArgs e)
        {
            MachineResource.Instance.Save(Properties.Settings.Default.ConfigName);
            SystemConfig.Instance.Save();
            SystemInfo.ShowToastInfo(this,"保存参数成功!", false);
        }

        private void btn_AddModule_Click(object sender, EventArgs e)
        {
            List<string> moduleNames = new List<string>();
            foreach (var item in sTC_Module.Tabs)
            {
                moduleNames.Add((item as SuperTabItem).Name);
            }
            FormAddModule frmAddModule = new FormAddModule(moduleNames);
            frmAddModule.StartPosition = FormStartPosition.CenterScreen;
            if(frmAddModule.ShowDialog() == DialogResult.OK)
            {
                AddNewModule(frmAddModule.ModuleName);
                sTC_Module.SelectedTabIndex = sTC_Module.Tabs.Count - 1;
                MachineResource.Instance.Save(Properties.Settings.Default.ConfigName);
                List<string> names = new List<string>();
                foreach (var item in sTC_Module.Tabs)
                {
                    names.Add((item as SuperTabItem).Name);
                }
                _mainForm.HomeForm.UpdateModuleInfo(names);
            }
        }
        public void ChangeModuleSelection(string name)
        {
            foreach (var item in sTC_Module.Tabs)
            {
                if((item as SuperTabItem).Name.Equals(name))
                {
                    sTC_Module.SelectedTab = (item as SuperTabItem);
                    sB_Debug.Value = true;
                    break;
                }
            }
        }
        public void AddNewModule(string moduleName, bool isCreate = true)
        {
            SuperTabItem superTabItem1 = new SuperTabItem();
            SuperTabControlPanel superTabControlPanel1 = new SuperTabControlPanel();
            // 
            // superTabItem1
            // 
            superTabItem1.AttachedControl = superTabControlPanel1;
            superTabItem1.GlobalItem = false;
            superTabItem1.Name = moduleName;
            superTabItem1.Text = moduleName;
            // 
            // superTabControlPanel1
            // 
            superTabControlPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
            superTabControlPanel1.Name = "superTabControlPanel1";
            superTabControlPanel1.TabItem = superTabItem1;

            sTC_Module.Tabs.Add(superTabItem1);
            this.sTC_Module.Controls.Add(superTabControlPanel1);

            ModuleControl moduleControl = new ModuleControl(SystemConfig.Instance.CardConfig);
            if (isCreate)
            {
                if (SystemConfig.Instance.ModuleSplitDistance.ContainsKey(moduleName))
                    SystemConfig.Instance.ModuleSplitDistance[moduleName] = moduleControl.ContainerSplitDistance;
                else
                    SystemConfig.Instance.ModuleSplitDistance.Add(moduleName, moduleControl.ContainerSplitDistance);
            }
            else
            {
                if (!SystemConfig.Instance.ModuleSplitDistance.ContainsKey(moduleName))
                    SystemConfig.Instance.ModuleSplitDistance.Add(moduleName, new List<int>());
                moduleControl.ContainerSplitDistance = SystemConfig.Instance.ModuleSplitDistance[moduleName];
            }
            moduleControl.ModuleName = moduleName;
            moduleControl.Dock = DockStyle.Fill;
            this.sTC_Module.Tabs[moduleName].Tag = moduleControl;
            superTabControlPanel1.Controls.Add(moduleControl);
        }

        private void FormModule_Load(object sender, EventArgs e)
        {
            List<string> moduleNames = new List<string>();
            foreach (var item in SingletonProvider<MachineResource>.Instance.MachineAxis.Values)
            {
                if(!moduleNames.Contains(item.Module))
                    moduleNames.Add(item.Module);
            }
            foreach (var item in SingletonProvider<MachineResource>.Instance.MachineSensor.Values)
            {
                if (!moduleNames.Contains(item.Module))
                    moduleNames.Add(item.Module);
            }
            foreach (var item in SingletonProvider<MachineResource>.Instance.MachineCylinder.Values)
            {
                if (!moduleNames.Contains(item.Module))
                    moduleNames.Add(item.Module);
            }

            foreach (var item in moduleNames)
            {
                AddNewModule(item, false);
            }
            sTC_Module_SelectedTabChanged(null, null);

            foreach (var item in sTC_Module.Tabs)
            {
                foreach (Control c in (item as SuperTabItem).AttachedControl.Controls)
                {
                    if (c is ModuleControl)
                    {
                        (c as ModuleControl).ChangeEditMode(false);
                    }
                }
            }
        }

        private void sTC_Module_SelectedTabChanged(object sender, SuperTabStripSelectedTabChangedEventArgs e)
        {
            if (sTC_Module.SelectedTabIndex != -1)
            {
                foreach (SuperTabItem item in sTC_Module.Tabs)
                {
                    if ((item.AttachedControl as SuperTabControlPanel).Controls.Count > 0)
                        ((item.AttachedControl as SuperTabControlPanel).Controls[0] as ModuleControl).t_IO.Enabled = false;
                }
                if ((sTC_Module.SelectedTab.AttachedControl as SuperTabControlPanel).Controls.Count > 0)
                    ((sTC_Module.SelectedTab.AttachedControl as SuperTabControlPanel).Controls[0] as ModuleControl).t_IO.Enabled = true;
            }
        }

        private void sB_Debug_ValueChanged(object sender, EventArgs e)
        {
            if(!sB_Debug.Value)
            {
                if (_axisForm == null || _axisForm.IsDisposed)
                {
                    string moduleName = (sTC_Module.SelectedTab as SuperTabItem).Name;
                    _axisForm = new FormXYZR(moduleName, _mainForm);
                    //_axisForm.ContainerSplitDistance = SystemConfig.Instance.ModuleSplitDistance[$"{moduleName}-Debug"];
                    _axisForm.TopLevel = false;
                    _axisForm.Dock = DockStyle.Fill;
                    panelEx1.Controls.Add(_axisForm);
                    switch (moduleName)
                    {
                        case "上料仓模组":
                            _axisForm.ZNames = new List<string>() { "上料仓来料顶升", "上料仓空盘顶升" };
                            _axisForm.HNames = new List<string>() { "上料仓Y轴" };
                            break;
                        case "下料仓模组":
                            _axisForm.ZNames = new List<string>() { "下料仓满盘顶升", "下料仓空盘顶升" };
                            _axisForm.HNames = new List<string>() { "下料仓Y轴" };
                            break;
                        case "精定位模组":
                            _axisForm.HNames = new List<string>() { "精定区Y轴" };
                            break;
                        case "NG模组":
                            //_axisForm.HNames = new List<string>() { "NG下料区Y轴" };
                            break;
                        case "上料移载":
                            _axisForm.XYNames = "上料移载X轴,上料仓Y轴";
                            if (SingletonProvider<MachineResource>.Instance.MachineAxis[_axisForm.XYNames.Split(',')[1]].ShowLocation < 4)
                                SingletonProvider<MachineResource>.Instance.MachineAxis[_axisForm.XYNames.Split(',')[1]].ShowLocation = 4;
                            _axisForm.RNames = new List<string>() { "上料移载U轴" };
                            _axisForm.ZNames = new List<string>() { "上料移载Z轴" };
                            break;
                        case "测试移载":
                            _axisForm.XYNames = "测试移载X轴,精定区Y轴";
                            if (SingletonProvider<MachineResource>.Instance.MachineAxis[_axisForm.XYNames.Split(',')[1]].ShowLocation < 4)
                                SingletonProvider<MachineResource>.Instance.MachineAxis[_axisForm.XYNames.Split(',')[1]].ShowLocation = 4;
                            _axisForm.RNames = new List<string>() { "测试移载U轴" };
                            _axisForm.ZNames = new List<string>() { "测试移载Z轴" };
                            break;
                        case "下料移载":
                            _axisForm.XYNames = "下料移载X轴,下料仓Y轴";
                            if (SingletonProvider<MachineResource>.Instance.MachineAxis[_axisForm.XYNames.Split(',')[1]].ShowLocation < 4)
                                SingletonProvider<MachineResource>.Instance.MachineAxis[_axisForm.XYNames.Split(',')[1]].ShowLocation = 4;
                            _axisForm.RNames = new List<string>() { "下料移载U轴" };
                            _axisForm.ZNames = new List<string>() { "下料移载Z轴" };
                            _axisForm.HNames = new List<string>() { "NG下料区Y轴" };
                            break;
                    }
                    _axisForm.Sensors = SingletonProvider<MachineResource>.Instance.MachineSensor.Values.Where(s => s.Module.Equals(moduleName)).ToList();
                    _axisForm.Cylinders = SingletonProvider<MachineResource>.Instance.MachineCylinder.Values.Where(s => s.Module.Equals(moduleName)).ToList();
                    sTC_Module.Visible = false;
                    _axisForm.Show();
                }
                else
                {
                    sTC_Module.Visible = false;
                    _axisForm.Show();
                }
            }
            else
            {
                if (_axisForm != null)
                    _axisForm.Close();
                sTC_Module.Visible = true;
            }
        }

        private void btn_Export_Click(object sender, EventArgs e)
        {
            string errInfo = "";
            List<Cylinder> cylinders = MachineResource.Instance.MachineCylinder.Values.ToList();
            CsvOperator<Cylinder> co = new CsvOperator<Cylinder>();
            co.WriteCSV(@"C:\\OUT.csv", cylinders, out errInfo);
            if (!string.IsNullOrEmpty(errInfo))
            {
                MessageBox.Show(errInfo);
            }

            List<Sensor> sensors = MachineResource.Instance.MachineSensor.Values.ToList();
            CsvOperator<Sensor> so = new CsvOperator<Sensor>();
            so.WriteCSV(@"C:\\IN.csv", sensors, out errInfo);
            if (!string.IsNullOrEmpty(errInfo))
            {
                MessageBox.Show(errInfo);
            }

            List<Axis> axes = MachineResource.Instance.MachineAxis.Values.ToList();
            CsvOperator<Axis> ao = new CsvOperator<Axis>();
            ao.WriteCSV(@"C:\\Axis.csv", axes, out errInfo);
            if (!string.IsNullOrEmpty(errInfo))
            {
                MessageBox.Show(errInfo);
            }
        }

        private void btn_Import_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "文件|*.csv";
            if(ofd.ShowDialog() == DialogResult.OK)
            {
                lock (MachineResource.Instance.GetLockObject())
                {
                    if (ofd.FileName.Contains("OUT"))
                    {
                        List<Cylinder> cylinders = new List<Cylinder>();
                        CsvOperator<Cylinder> co = new CsvOperator<Cylinder>();
                        string errInfo = "";
                        co.ReadCSV(ofd.FileName, out cylinders, out errInfo);
                        if (!string.IsNullOrEmpty(errInfo))
                        {
                            MessageBox.Show(errInfo);
                        }
                        if (cylinders != null && cylinders.Count > 0)
                        {
                            foreach (SuperTabItem item in sTC_Module.Tabs)
                            {
                                (item.Tag as ModuleControl).ClearCylinder();
                            }
                            MachineResource.Instance.MachineCylinder.Clear();
                        }
                        foreach (var item in cylinders)
                        {
                            if (sTC_Module.Tabs.Contains(item.Module))
                            {
                                (sTC_Module.Tabs[item.Module].Tag as ModuleControl).AddDigitalOutput(item.Description, false, false, item.ControlCardName1, item.ID1, item, item.ControlCardName2, item.ID2, String.Join(",", item.OriginNames), String.Join(",", item.MoveNames));
                                MachineResource.Instance.MachineCylinder.Add(item.Description, item);
                            }
                        }
                    }
                    else if (ofd.FileName.Contains("IN"))
                    {
                        List<Sensor> sensors = new List<Sensor>();
                        CsvOperator<Sensor> co = new CsvOperator<Sensor>();
                        string errInfo = "";
                        co.ReadCSV(ofd.FileName, out sensors, out errInfo);
                        if (!string.IsNullOrEmpty(errInfo))
                        {
                            MessageBox.Show(errInfo);
                        }
                        if (sensors != null && sensors.Count > 0)
                        {
                            foreach (SuperTabItem item in sTC_Module.Tabs)
                            {
                                (item.Tag as ModuleControl).ClearSensor();
                            }
                            MachineResource.Instance.MachineSensor.Clear();
                        }
                        foreach (var item in sensors)
                        {
                            if (sTC_Module.Tabs.Contains(item.Module))
                            {
                                (sTC_Module.Tabs[item.Module].Tag as ModuleControl).AddDigitalInput(item.Description, false, item.ControlCardName, item.ID, item.AlwaysOn, item);
                                MotionFactory.Instance.InitializeSensor(SingletonProvider<MachineResource>.Instance, item);
                                MachineResource.Instance.MachineSensor.Add(item.Description, item);
                            }
                            else
                            {

                            }
                        }
                    }
                    else if (ofd.FileName.Contains("Axis"))
                    {
                        List<Axis> axes = new List<Axis>();
                        CsvOperator<Axis> co = new CsvOperator<Axis>();
                        string errInfo = "";
                        co.ReadCSV(ofd.FileName, out axes, out errInfo);
                        if (!string.IsNullOrEmpty(errInfo))
                        {
                            MessageBox.Show(errInfo);
                        }
                        if (axes != null && axes.Count > 0)
                        {
                            foreach (SuperTabItem item in sTC_Module.Tabs)
                            {
                                (item.Tag as ModuleControl).ClearAxis();
                            }
                            MachineResource.Instance.MachineAxis.Clear();
                        }
                        foreach (var item in axes)
                        {
                            if (sTC_Module.Tabs.Contains(item.Module))
                            {
                                (sTC_Module.Tabs[item.Module].Tag as ModuleControl).AddAxis(item.Description, 0, "ALM.png", item.ControlCardName, item.ID, item.IsStep, (int)item.ConvertRate, item.HomeMode, item.HomeDirP, 100, 0, 0, 0.1, 0.1, 0.05, item);
                                MachineResource.Instance.MachineAxis.Add(item.Description, item);
                            }
                        }
                    }
                    MotionFactory.Instance.InitializeMotion2(MachineResource.Instance);
                    MachineResource.Instance.Save(Properties.Settings.Default.ConfigName);
                }
            }
        }

        private void btn_RemoveModule_Click(object sender, EventArgs e)
        {
            string moduleName = sTC_Module.SelectedTab.Name;
            if(MessageBox.Show($"确定删除 {moduleName} 模组吗?", "删除模组", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
            {
                lock (MachineResource.Instance.GetLockObject())
                {
                    //删除模组
                    List<string> keys = new List<string>();
                    foreach (var item in MachineResource.Instance.MachineAxis.Where(kvp => kvp.Value.Module.Equals(moduleName)))
                    {
                        keys.Add(item.Key);
                    }
                    keys.ForEach(k => MachineResource.Instance.MachineAxis.Remove(k));
                    foreach (var item in MachineResource.Instance.MachineCylinder.Where(kvp => kvp.Value.Module.Equals(moduleName)))
                    {
                        keys.Add(item.Key);
                    }
                    keys.ForEach(k => MachineResource.Instance.MachineCylinder.Remove(k));
                    foreach (var item in MachineResource.Instance.MachineSensor.Where(kvp => kvp.Value.Module.Equals(moduleName)))
                    {
                        keys.Add(item.Key);
                    }
                    keys.ForEach(k => MachineResource.Instance.MachineSensor.Remove(k));
                    foreach (var item in MachineResource.Instance.MachineCoordinates.Where(kvp => kvp.Value.Module.Equals(moduleName)))
                    {
                        keys.Add(item.Key);
                    }
                    keys.ForEach(k => MachineResource.Instance.MachineCoordinates.Remove(k));
                    foreach (var item in MachineResource.Instance.MachinePdo.Where(kvp => kvp.Value.Module.Equals(moduleName)))
                    {
                        keys.Add(item.Key);
                    }
                    keys.ForEach(k => MachineResource.Instance.MachinePdo.Remove(k));
                    MachineResource.Instance.ModulePaths.Remove(moduleName);
                    MachineResource.Instance.ModuleTrays.Remove(moduleName);
                    MachineResource.Instance.Save(Properties.Settings.Default.ConfigName);
                    //删除界面
                    sTC_Module.Tabs.Remove(sTC_Module.SelectedTab);
                    //删除主界面
                    List<string> names = new List<string>();
                    foreach (var item in sTC_Module.Tabs)
                    {
                        names.Add((item as SuperTabItem).Name);
                    }
                    _mainForm.HomeForm.UpdateModuleInfo(names);
                }
            }
        }

        private void btn_ReviseModule_Click(object sender, EventArgs e)
        {
            List<string> moduleNames = new List<string>();
            foreach (var item in sTC_Module.Tabs)
            {
                moduleNames.Add((item as SuperTabItem).Name);
            }
            string oldName = sTC_Module.SelectedTab.Name;
            FormAddModule frmAddModule = new FormAddModule(moduleNames, sTC_Module.SelectedTab.Name);
            frmAddModule.StartPosition = FormStartPosition.CenterScreen;
            if (frmAddModule.ShowDialog() == DialogResult.OK)
            {
                foreach (var item in MachineResource.Instance.MachineAxis.Values)
                {
                    item.Module = frmAddModule.ModuleName;
                }
                foreach (var item in MachineResource.Instance.MachineCylinder.Values)
                {
                    item.Module = frmAddModule.ModuleName;
                }
                foreach (var item in MachineResource.Instance.MachineSensor.Values)
                {
                    item.Module = frmAddModule.ModuleName;
                }
                if (MachineResource.Instance.ModuleTrays.ContainsKey(oldName))
                {
                    SerializableDictionary<string, Tray> trays = MachineResource.Instance.ModuleTrays[oldName];
                    MachineResource.Instance.ModuleTrays.Remove(oldName);
                    MachineResource.Instance.ModuleTrays.Add(frmAddModule.ModuleName, trays);
                }
                if (MachineResource.Instance.ModulePaths.ContainsKey(oldName))
                {
                    SerializableDictionary<string, PointPath> paths = MachineResource.Instance.ModulePaths[oldName];
                    MachineResource.Instance.ModulePaths.Remove(oldName);
                    MachineResource.Instance.ModulePaths.Add(frmAddModule.ModuleName, paths);
                }
                sTC_Module.SelectedTab.Text = frmAddModule.ModuleName;
                sTC_Module.SelectedTab.Name = frmAddModule.ModuleName;
                _mainForm.HomeForm.UpdateModuleInfo(MachineResource.Instance.GetAllModuleNames());
                MachineResource.Instance.Save(Properties.Settings.Default.ConfigName);
            }
        }
        public void UserChanged()
        {
            if (GlobalVariable.UserRole.UserLevel == 0)
            {
                sB_Debug.Enabled = false;
                foreach (var item in sTC_Module.Tabs)
                {
                    foreach (Control c in (item as SuperTabItem).AttachedControl.Controls)
                    {
                        if (c is ModuleControl)
                        {
                            (c as ModuleControl).ChangeEditMode(false);
                        }
                    }
                }
            }
            else
            {
                sB_Debug.Enabled = true;
                foreach (var item in sTC_Module.Tabs)
                {
                    foreach (Control c in (item as SuperTabItem).AttachedControl.Controls)
                    {
                        if (c is ModuleControl)
                        {
                            (c as ModuleControl).ChangeEditMode(true);
                        }
                    }
                }
            }
        }

        private void btn_SaveModule_Click(object sender, EventArgs e)
        {
            if(!FlowManager.Instance.PauseFlag)
            {
                SystemInfo.ShowToastInfo(this, "保存模组配置需要暂停!", true);
                return;
            }

            lock (GlobalVariable.SaveConfigLock)
            {
                //Verify
                foreach (var item in sTC_Module.Tabs)
                {
                    foreach (Control c in (item as SuperTabItem).AttachedControl.Controls)
                    {
                        if (c is ModuleControl)
                        {
                            if (!(c as ModuleControl).VerifyConfig())
                            {
                                return;
                            }
                        }
                    }
                }
                //Clear
                //SingletonProvider<MachineResource>.Instance.MachineAxis.Clear();
                //SingletonProvider<MachineResource>.Instance.MachineSensor.Clear();
                //SingletonProvider<MachineResource>.Instance.MachineCylinder.Clear();
                ////Save
                foreach (var item in sTC_Module.Tabs)
                {
                    foreach (Control c in (item as SuperTabItem).AttachedControl.Controls)
                    {
                        if (c is ModuleControl)
                        {
                            (c as ModuleControl).SaveLayout();
                        }
                    }
                }
                //_axisForm.SaveLayout();

                //MachineResource.Instance.Save(Properties.Settings.Default.ConfigName);
                //SystemConfig.Instance.Save();
                MotionFactory.Instance.InitializeMotion2(SingletonProvider<MachineResource>.Instance);
            }
            SystemInfo.ShowToastInfo(this, "保存配置成功!", false);
        }
    }
}
